//#include <iostream>
//#include <thread>
//#include <mutex>
//#include <vector>
//#include <queue>
//#include <functional>
//#include <condition_variable>
//#include <sys/socket.h>
//#include <netinet/in.h>
//#include <arpa/inet.h>
//#include <fstream>
//#include <unistd.h>
//#include <future>
//
//
//class ThreadPool {
//private:
//    std::vector<std::thread> threads; // 线程对象容器
//    std::queue<std::function<void()>> tasks; // 任务队列
//    
//    std::mutex queue_mutex;
//    std::condition_variable condition;
//    bool stop; // 用于指示线程池是否应该停止运行。初始化为 false，表示线程池开始时不应该停止 
//    
//public:
//    ThreadPool(size_t num_threads) : stop(false) {
//        for (size_t i = 0; i < num_threads; i++) {
//            // 创建一个线程对象
//            threads.emplace_back([this] {
//                // 定义线程对象的行为
//                while (true) {
//                    // 存储待执行任务的 std::function 对象，std::function<void()> 是一个可以存储任何可调用对象（函数、Lambda 表达式等）的容器
//                    std::function<void()> task;
//                    
//                    // 从任务队列中取任务
//                    // std::unique_lock 的生命周期与其所属的作用域（大括号 {}）一致。一旦 unique_lock 对象超出其作用域，它会自动释放锁
//                    {
//                        // 独占的互斥锁 lock，用于保护对任务队列的访问，以防止多个线程同时修改它而导致数据竞争和不确定的行为
//                        std::unique_lock<std::mutex> lock(queue_mutex);
//                        
//                        // 一个等待循环，线程在这里等待条件满足（即 stop=true 或者任务队列不为空）
//                        // lock 作为参数传递给 wait 函数的互斥锁，会在等待过程中被释放，允许其他线程获取这个锁
//                        condition.wait(lock, [this] { return stop || !tasks.empty(); });
//                        
//                        // 再次检查，若 stop=true 且任务队列为空时能退出循环，而不是等待条件再次满足
//                        if (stop && tasks.empty()) {
//                            return;
//                        }
//                        
//                        task = std::move(tasks.front());
//                        tasks.pop();
//                    } // 该线程自动释放锁
//                    
//                    task();
//                }
//            });
//        }
//    }
//    
//    ~ThreadPool() {
//        // 代码块限制 std::unique_lock 对象 lock 的生命周期，确保在代码块结束时自动释放锁
//        {
//            // 独占的互斥锁，用于保护对 ThreadPool 对象的操作
//            std::unique_lock<std::mutex> lock(queue_mutex);
//            // 表示线程池应该停止运行
//            stop = true;
//        }
//        
//        // 调用 condition（条件变量）的 notify_all 函数，用于唤醒所有正在等待的线程
//        // 这是为了通知等待在条件变量上的线程，以便它们能够检查 stop 标志并在必要时退出循环
//        condition.notify_all();
//        
//        // 对每个工作线程调用 join 函数，等待线程的结束
//        // join 会阻塞调用线程，直到被调用的线程执行完成。这确保了在销毁 ThreadPool 对象之前，所有工作线程都已经执行完毕
//        for (std::thread& thread : threads) {
//            thread.join();
//        }
//    }
//    
//    template <class F, class... Args> // 模板函数，可以接受任意类型的可调用对象（函数、Lambda 表达式等）和其参数
//    void enqueue(F&& f, Args&&... args) {
//        // std::unique_lock 对象 lock，用于锁住 queue_mutex。确保在修改任务队列时是线程安全的，防止多个线程同时修改导致数据竞争
//        {
//            std::unique_lock<std::mutex> lock(queue_mutex);
//            
//            // 使用 emplace 函数将一个新任务添加到任务队列中
//            // 任务是一个 Lambda 表达式，它捕获了传递给 enqueue 函数的可调用对象 f 和其参数 args
//            // [=] 表示捕获外部所有变量。使用 std::forward 转发传递给 enqueue 函数的参数 args
//            // tasks.emplace([=] { std::forward<F>(f)(std::forward<Args>(args)...); });
//            auto task = std::make_shared<std::packaged_task<void()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
//            tasks.emplace([task]() { (*task)(); });
//        } // 自动释放互斥锁 queue_mutex
//        
//        // 调用条件变量 condition 的 notify_one 函数，通知等待在条件上的某一个线程有新的任务到来，以便它能够从等待状态中唤醒并执行任务
//        condition.notify_one();
//    }
//};
//
//// 使用 ThreadPool 的 handle_client 函数
//void handle_client(int client_socket) {
//    std::ifstream html_file("index.html");
//    std::string html_content((std::istreambuf_iterator<char>(html_file)), std::istreambuf_iterator<char>());
//    
//    // 构建HTTP响应头
//    std::string response = "HTTP/1.1 200 OK\r\n";
//    response += "Content-Length: " + std::to_string(html_content.size()) + "\r\n";
//    response += "Content-Type: text/html\r\n\r\n";
//    
//    // 发送HTTP响应头和HTML内容给客户端
//    send(client_socket, response.c_str(), response.size(), 0);
//    send(client_socket, html_content.c_str(), html_content.size(), 0);
//    
//    // 关闭连接
//    close(client_socket);
//}
//
//int main() {
//    const int PORT = 8089;
//    const int BACKLOG = 5; // 最大连接数
//    const size_t THREAD_POOL_SIZE = 4;  // 设置线程池大小
//    
//    // 全局互斥锁，用于保护对 std::cout 的访问
//    std::mutex cout_mutex;
//    
//    
//    // 服务器socket设置和绑定的部分
//    // 创建服务器socket
//    int server_socket = socket(AF_INET, SOCK_STREAM, 0);
//    if (server_socket == -1) {
//        perror("Error creating server socket");
//        return 1;
//    }
//    
//    // 设置服务器地址结构 sockaddr_in
//    sockaddr_in server_address{};
//    server_address.sin_family = AF_INET;
//    server_address.sin_addr.s_addr = INADDR_ANY;  // 监听所有网络接口
//    server_address.sin_port = htons(PORT);        // 设置监听的端口
//    
//    // 绑定服务器 socket 到地址结构
//    if (bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)) == -1) {
//        perror("Error binding server socket");
//        close(server_socket);
//        return 1;
//    }
//    
//    if (listen(server_socket, BACKLOG) == -1) {
//        perror("Error listening on server socket");
//        close(server_socket);
//        return 1;
//    }
//    
//    
//    ThreadPool thread_pool(THREAD_POOL_SIZE);  // 创建线程池
//    
//    std::cout << "Press 'q' and Enter to quit: ";
//    // 等待用户输入来停止程序
//    char userInput;
//    
//    while (true) {
//        std::cin >> userInput;
//        if (userInput == 'q') {
//            break;  // 退出循环，停止程序
//        }
//        
//        sockaddr_in client_address{}; // 结构体 sockaddr_in，用于存储客户端的地址信息
//        socklen_t client_address_size = sizeof(client_address); // 获取 sockaddr_in 结构体的大小，用于传递给 accept 函数
//        
//        int client_socket = accept(server_socket, (struct sockaddr*)&client_address, &client_address_size); // 接受客户端的连接请求
//        if (client_socket == -1) {
//            perror("Error accepting client connection");
//            continue;
//        }
//        
//        // 用于锁住 cout_mutex。这是为了确保输出到标准输出时是线程安全的
//        {
//            std::lock_guard<std::mutex> lock(cout_mutex);
//            std::cout << "Connection from " << inet_ntoa(client_address.sin_addr) << ":" << ntohs(client_address.sin_port) << std::endl;
//        }
//        
//        // 将处理客户端请求的任务添加到线程池中
//        thread_pool.enqueue(handle_client, client_socket);
//    }
//    
//    close(server_socket);
//    
//    return 0;
//}




#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <queue>
#include <functional>
#include <condition_variable>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fstream>
#include <unistd.h>
#include <future>


class ThreadPool {
private:
    std::vector<std::thread> threads; // 线程对象容器
    std::queue<std::function<void()>> tasks; // 任务队列
    
    std::mutex queue_mutex;
    std::condition_variable condition;
    bool stop; // 用于指示线程池是否应该停止运行。初始化为 false，表示线程池开始时不应该停止 
    
public:
    ThreadPool(size_t num_threads) : stop(false) {
        for (size_t i = 0; i < num_threads; i++) {
            // 创建一个线程对象
            threads.emplace_back([this] {
                // 定义线程对象的行为
                while (true) {
                    // 存储待执行任务的 std::function 对象，std::function<void()> 是一个可以存储任何可调用对象（函数、Lambda 表达式等）的容器
                    std::function<void()> task;
                    
                    // 从任务队列中取任务
                    // std::unique_lock 的生命周期与其所属的作用域（大括号 {}）一致。一旦 unique_lock 对象超出其作用域，它会自动释放锁
                    {
                        // 独占的互斥锁 lock，用于保护对任务队列的访问，以防止多个线程同时修改它而导致数据竞争和不确定的行为
                        std::unique_lock<std::mutex> lock(queue_mutex);
                        
                        // 一个等待循环，线程在这里等待条件满足（即 stop=true 或者任务队列不为空）
                        // lock 作为参数传递给 wait 函数的互斥锁，会在等待过程中被释放，允许其他线程获取这个锁
                        condition.wait(lock, [this] { return stop || !tasks.empty(); });
                        
                        // 再次检查，若 stop=true 且任务队列为空时能退出循环，而不是等待条件再次满足
                        if (stop && tasks.empty()) {
                            return;
                        }
                        
                        task = std::move(tasks.front());
                        tasks.pop();
                    } // 该线程自动释放锁
                    
                    task();
                }
                });
        }
    }
    
    ~ThreadPool() {
        // 代码块限制 std::unique_lock 对象 lock 的生命周期，确保在代码块结束时自动释放锁
        {
            // 独占的互斥锁，用于保护对 ThreadPool 对象的操作
            std::unique_lock<std::mutex> lock(queue_mutex);
            // 表示线程池应该停止运行
            stop = true;
        }
        
        // 调用 condition（条件变量）的 notify_all 函数，用于唤醒所有正在等待的线程
        // 这是为了通知等待在条件变量上的线程，以便它们能够检查 stop 标志并在必要时退出循环
        condition.notify_all();
        
        // 对每个工作线程调用 join 函数，等待线程的结束
        // join 会阻塞调用线程，直到被调用的线程执行完成。这确保了在销毁 ThreadPool 对象之前，所有工作线程都已经执行完毕
        for (std::thread& thread : threads) {
            thread.join();
        }
    }
    
    template <class F, class... Args> // 模板函数，可以接受任意类型的可调用对象（函数、Lambda 表达式等）和其参数
    void enqueue(F&& f, Args&&... args) {
        // std::unique_lock 对象 lock，用于锁住 queue_mutex。确保在修改任务队列时是线程安全的，防止多个线程同时修改导致数据竞争
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            
            // 使用 emplace 函数将一个新任务添加到任务队列中
            // 任务是一个 Lambda 表达式，它捕获了传递给 enqueue 函数的可调用对象 f 和其参数 args
            // [=] 表示捕获外部所有变量。使用 std::forward 转发传递给 enqueue 函数的参数 args
            // tasks.emplace([=] { std::forward<F>(f)(std::forward<Args>(args)...); });
            auto task = std::make_shared<std::packaged_task<void()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
            tasks.emplace([task]() { (*task)(); });
        } // 自动释放互斥锁 queue_mutex
        
        // 调用条件变量 condition 的 notify_one 函数，通知等待在条件上的某一个线程有新的任务到来，以便它能够从等待状态中唤醒并执行任务
        condition.notify_one();
    }
};

// 使用 ThreadPool 的 handle_client 函数
void handle_client(int client_socket) {
    std::ifstream html_file("index.html");
    std::string html_content((std::istreambuf_iterator<char>(html_file)), std::istreambuf_iterator<char>());
    
    // 构建HTTP响应头
    std::string response = "HTTP/1.1 200 OK\r\n";
    response += "Content-Length: " + std::to_string(html_content.size()) + "\r\n";
    response += "Content-Type: text/html\r\n\r\n";
    
    // 发送HTTP响应头和HTML内容给客户端
    send(client_socket, response.c_str(), response.size(), 0);
    send(client_socket, html_content.c_str(), html_content.size(), 0);
    
    // 测试，添加延时
    // 在处理完每个连接后添加适当的延迟，模拟服务器处理时间
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    
    // 关闭连接
    close(client_socket);
}

int main() {
    const int PORT = 8089;
    const int BACKLOG = 5000; // 最大连接数
    const size_t THREAD_POOL_SIZE = 1000;  // 设置线程池大小
    
    // 全局互斥锁，用于保护对 std::cout 的访问
    std::mutex cout_mutex;
    
    
    // 服务器socket设置和绑定的部分
    // 创建服务器socket
    int server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket == -1) {
        perror("Error creating server socket");
        return 1;
    }
    
    // 设置服务器地址结构 sockaddr_in
    sockaddr_in server_address{};
    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = INADDR_ANY;  // 监听所有网络接口
    server_address.sin_port = htons(PORT);        // 设置监听的端口
    
    // 绑定服务器 socket 到地址结构
    if (bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)) == -1) {
        perror("Error binding server socket");
        close(server_socket);
        return 1;
    }
    
    if (listen(server_socket, BACKLOG) == -1) {
        perror("Error listening on server socket");
        close(server_socket);
        return 1;
    }
    
    
    ThreadPool thread_pool(THREAD_POOL_SIZE);  // 创建线程池
    
    //std::cout << "Press 'q' and Enter to quit: ";
    // 等待用户输入来停止程序
    //char userInput;
    
    while (true) {
        //std::cin >> userInput;
        //if (userInput == 'q') {
        //break;  // 退出循环，停止程序
        //}
        
        sockaddr_in client_address{}; // 结构体 sockaddr_in，用于存储客户端的地址信息
        socklen_t client_address_size = sizeof(client_address); // 获取 sockaddr_in 结构体的大小，用于传递给 accept 函数
        
        int client_socket = accept(server_socket, (struct sockaddr*)&client_address, &client_address_size); // 接受客户端的连接请求
        if (client_socket == -1) {
            perror("Error accepting client connection");
            continue;
        }
        
        // 用于锁住 cout_mutex。这是为了确保输出到标准输出时是线程安全的
        {
            std::lock_guard<std::mutex> lock(cout_mutex);
            std::cout << "Connection from " << inet_ntoa(client_address.sin_addr) << ":" << ntohs(client_address.sin_port) << std::endl;
        }
        
        // 将处理客户端请求的任务添加到线程池中
        thread_pool.enqueue(handle_client, client_socket);
    }
    
    close(server_socket);
    
    return 0;
}

